Skip to content

Restrict supercache filename to a safe character set#1050

Merged
donnchawp merged 1 commit into
trunkfrom
fix/supercache-filename-handling
May 27, 2026
Merged

Restrict supercache filename to a safe character set#1050
donnchawp merged 1 commit into
trunkfrom
fix/supercache-filename-handling

Conversation

@donnchawp

Copy link
Copy Markdown
Contributor

Ensures the generated supercache filename is always a single, well-formed path segment.

The supercache_filename_str filter chain can return arbitrary data, so the assembled suffix is now restricted to a safe set of characters (a-zA-Z0-9_-) before the filename is built. Legitimate values (-https, -mobile, mobile group names) are unaffected.

Ensure the generated supercache filename is always a single, well-formed path segment regardless of what filters return.
@donnchawp donnchawp merged commit 60bd350 into trunk May 27, 2026
6 checks passed
@donnchawp donnchawp deleted the fix/supercache-filename-handling branch May 27, 2026 18:01
donnchawp added a commit that referenced this pull request Jun 17, 2026
* Add two-tier PHP test harness (#1051)

Make the procedural caching functions reachable from PHPUnit, split into
two tiers by what they need to run:

Smoke tier (CI, no database, no WordPress runtime):
- tests/php/bootstrap-smoke.php loads the procedural files and provides a
  minimal pure-PHP filter registry (add_filter/apply_filters/
  remove_all_filters) standing in for WordPress's hook system.
- Tests in tests/php/smoke/ for supercache_filename() (a #1050
  filename-sanitization regression guard), wpsc_get_realpath() +
  wpsc_is_in_cache_directory(), get_wp_cache_key(), plus the existing
  accept-header test moved in.
- phpunit.{9,11,12}.xml.dist now target the smoke bootstrap + tests/php/smoke.

Integration tier (local only, via `make test-integration`):
- tests/php/bootstrap-integration.php loads the WordPress test library and
  the procedural files under a real WP runtime + database. No apply_filters
  stub — WordPress core defines the real one.
- Runs in the wp-env Docker environment. Because WP_UnitTestCase is not
  PHPUnit 10+ compatible while the smoke tier runs modern PHPUnit, the
  integration tier uses an isolated PHPUnit 9 toolchain in tests/php/tools/.
- phpunit-integration.{9,11,12}.xml.dist + tests/php/wp-tests-config.php
  (env-driven, wp-env defaults).

Other:
- Makefile: `make test` (smoke) and `make test-integration` (Docker).
- .wp-env.json bumped to PHP 8.3 (drops deprecated testsEnvironment key).
- tests/php/README.md documents the copyable pattern for each tier.

* Use PHPUnit 9.6 for both tiers; drop isolated toolchain

WordPress's WP_UnitTestCase calls PHPUnit\Util\Test::parseTestMethodAnnotations(),
removed in PHPUnit 10+, so the integration tier is capped at PHPUnit 9.6 (verified
against PHPUnit 10.5 and 12.5 — both fatal). Rather than run the smoke tier on
modern PHPUnit and the integration tier on an isolated 9.x toolchain, pin the
whole project to PHPUnit 9.6, matching the version WordPress core tests against.

- composer.json: pin phpunit/phpunit ^9.6; wp-phpunit back in root require-dev.
- Remove tests/php/tools/ (the isolated PHPUnit 9 toolchain) entirely.
- Remove phpunit.{11,12}.xml.dist and phpunit-integration.{11,12}.xml.dist;
  only the .9 configs remain.
- bootstrap-integration.php: drop the WPSC_INTEGRATION_AUTOLOAD indirection —
  both tiers share the root vendor again.
- Makefile: test-integration runs vendor/bin/phpunit directly (no isolated
  install, no platform pin, no env-var plumbing).
- README: note both tiers run on PHPUnit 9.6 and why.

Verified: composer test-php (smoke, PHP 8.5) OK 34/42; make test-integration
(real WP + DB) OK 2/2.

* Use @Covers annotations instead of inert CoversFunction attributes

PHPUnit 9.6 (the version the project is now pinned to) does not read the
#[CoversFunction] attribute API (PHPUnit 10+), so the attributes recorded no
coverage attribution. Switch the smoke tests and the README example to the
9.x-native @Covers ::function annotation so coverage runs (composer
test-coverage) attribute coverage to the function under test.

* Harden integration bootstrap and document pcntl dependency

Code-review follow-ups:
- Guard _wpsc_manually_load_procedural_files() with function_exists() so the
  integration bootstrap can't fatal on redeclaration if the plugin is ever
  active in the tests env and loads wp-cache-phase2.php via WPCACHEHOME.
- README: note that the composer test-php / phpunit scripts use pcntl (via
  phpunit-select-config) and how to run PHPUnit directly without it.

* Use locally-installed @wordpress/env instead of npx --yes

npx --yes @wordpress/env re-resolves the package against the npm registry on
every make invocation, which fails behind registry proxies that gate or block
fetches. Pin @wordpress/env as a devDependency and point the Makefile at
node_modules/.bin/wp-env so it resolves locally after a one-time npm install
(make install), with no per-run registry round-trip.

* Guard wp-env make targets with a friendly 'run make install' error

Add a file-target rule for node_modules/.bin/wp-env that exits with a clear
message when the binary is missing, and make every wp-env target depend on it.
Replaces the raw 'No such file or directory' failure when wp-env hasn't been
installed yet.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant